<?php
class PsytestController extends CController {
    public $defaultAction = 'list';

	public function filters() {
		return array(
				'accessControl'
		);
	}
	
	
	public function accessRules() {
		return array(
			array(
				'allow',
				'users' => array('@')
			),
            array(
				'deny',
                'users' => array('?'),
                'actions' => array('createcomment')
			),
		);
	}
    
	public function actions() {
		return array(
			// Captcha action renders the CAPTCHA image
			'captcha' => array(
				'class' => 'CCaptchaAction',
				'backColor' => 0xF5F5F5,
				'foreColor' => 0x6C8D00,
				'maxLength' => 5,
				'minLength' => 5,
				'padding' => 2,
				'height' => 30,
				'width' => 80
			)
		);
	}
    
	public function actionIndex() {
        $topic = $this->loadTestTopic();
        if($topic !== null) {
            if( ! $topic->hasState()) {
                $topic->resetState();
            }
            $conclusions = array();
            $isViewConclusion = false;
            $isRedo = isset($_GET['redo']) && $_GET['redo'] == '1' ? true : false;
            $userId = Yii::app()->user->id;
            // Check if having been tested
            $hasTested = false;
            if(($hasTested = $topic->hasTested()) === false || $isRedo) {
            	if($isRedo) {
            		$topic->resetState();
            	}
                // If not, get a question or a conclusion
                $question = TestQuestions::model()->getCurrentQuestion($topic);
                $isViewConclusion = $question === null ? true : false;
                if($isViewConclusion) {
                    if($userId === null) {
                        Yii::app()->user->setReturnUrl($this->createAbsoluteUrl('/psytest/index', array('id' => $topic->topicId)));
                        $this->redirect(array('/users/signin'));
                    }
                    $conclusions = $this->getConclusions($topic);
                    $this->logUserPsyTest($topic, $conclusions);
                }
            } else {
                if($userId !== null) {
                    // If yes, get the log
                    $isViewConclusion = true;
                    $userPsytest = UserPsytest::model()->findByAttributes(array('userId' => $userId, 'topicId' => $topic->topicId));
                    $conclusionIds = $userPsytest->getConclusionIds();
                    foreach($conclusionIds as $conclusionId) {
                        $conclusion = TestConclusions::model()->findByPk($conclusionId);
                        if($topic->getTypeCatalog() == 'mark') {
                            $dim2Mark = $this->getDim2Mark($topic, $userPsytest->getState());
                            $replacement = $this->getConclusionReplacement($topic, $dim2Mark);
                            $conclusion = $this->translateConclusionDescr($conclusion, $replacement);
                        }
                        $conclusions[] = $conclusion;
                    }
                }
            }

            $psytestForm = new PsytestForm;

            $criteria  = new CDbCriteria;
            $criteria->condition = 'psyTestCategoryId = '.$topic->psyTestCategoryId.' AND topicId != '.$topic->topicId;
            $criteria->order = 'topicId DESC';
            $criteria->limit = 10;
            $otherTopics = TestTopics::model()->findAll($criteria);

            Yii::app()->clientScript->registerScriptFile(Yii::app()->baseUrl.'/assets/jquery.form.js', CClientScript::POS_HEAD);
            $this->setPageTitle($topic->topicTitle.'_心理测验|心理测试_广州心理咨询网');
            if($topic->metaKey != '') {
                Yii::app()->clientScript->registerMetaTag(htmlspecialchars($topic->metaKey), 'keywords');
            }
            if($topic->metaDescr != '') {
                Yii::app()->clientScript->registerMetaTag(htmlspecialchars($topic->metaDescr), 'description');
            }
            $this->render('index',
                array(
                    'topic' => $topic,
                    'question' => isset($question) ? $question : null,
                    'psytestForm' => $psytestForm,
                    'isViewConclusion' => $isViewConclusion,
                    'conclusions' => $conclusions,
                	'hasTested' => $hasTested,
                	'isRedo' => $isRedo,
                    'otherTopics' => $otherTopics,
                	'_comment' => Yii::app()->user->hasFlash('testComment') ? unserialize(Yii::app()->user->getFlash('testComment')) : new TestComments
                )
            );
        }
	}

    public function getDim2Mark($topic, $state) {
        $dim2Mark = array();
        foreach($topic->dimens as $dim) {
        	$dim2Mark[$dim->dimensId] = 0;
        }
        foreach($topic->questions as $question) {
            if(isset($state[$question->questionId])) {
                $answerId = $state[$question->questionId];
                // For $dim2Mark, the $key => $value is dimensionalityID => mark on this dimensionality
                $marks = TestAnswerMark::model()->findAll('answerId = '.$answerId);
                foreach($marks as $mark) {
//                    if( ! isset($dim2Mark[$mark->dimensId])) {
//                        $dim2Mark[$mark->dimensId] = 0;
//                    }
                    // Calculate overall mark on corresponding dimensionality
                    $dim2Mark[$mark->dimensId] += $mark->mark;
                }
            } else {
                // throw exception
                return ;
            }
        }
        return $dim2Mark;
    }

    public function getConclusionReplacement($topic, $dim2Mark) {
        $replacement = array();
        foreach($topic->dimens as $dim) {
            $replacement[$dim->getReplacer()] = $dim2Mark[$dim->dimensId];
        }
        if($topic->hasSecDim) {
            // 计算二次维度
            foreach($topic->secDims as $secDim) {
                $exp = 'return ';
                $exp .= strtr($secDim->formula, $replacement);
                $exp .= ';';
                $replacement[$secDim->getReplacer()] = @eval($exp);
            }
        }
        return $replacement;
    }

    public function translateConclusionDescr($conclusion, $replacement) {
        $conclusion->conclusionDescr = strtr($conclusion->conclusionDescr, $replacement);
        return $conclusion;
    }

//    public function actionRedo() {
//        $topic = $this->loadTestTopic();
//        if($topic !== null) {
//            $topic->resetState();
//        }
//    }

	public function actionList() {
        $categoryId = isset($_GET['id']) ? (int)$_GET['id'] : null;
        $criteria = new CDbCriteria;
        $category = null;
        if($categoryId !== null) {
            $criteria->condition = 'psyTestCategoryId = '.$categoryId;
            $category = TestCategories::model()->findByPk($categoryId);
        }
        $criteria->order = 'topicId DESC';
        $topicsCount = TestTopics::model()->published()->count($criteria);
		// Pagination
		$pages = new CPagination($topicsCount);
		$pages->pageSize = 10;
		$pages->applyLimit($criteria);
        $topics = TestTopics::model()->published()->findAll($criteria);
        
        $categories = TestCategories::model()->findAll();
        
        $pageTitle = ! isset($category) && $category === null ? '' : $category->categoryName.'_';
        $pageTitle .= '心理测试|心理测验|心理测评_广州心理咨询网';
        $metaKeywords = '心理测试,心理测验,心理测评';
        Yii::app()->clientScript->registerMetaTag(!isset($category) && $category === null ? $metaKeywords : $category->categoryName.','.$metaKeywords, 'keywords');
        Yii::app()->clientScript->registerMetaTag(!isset($category) && $category === null ? '所有心理测验,心理测评,心理测试' : '关于'.$category->categoryName.'的心理测验心理测评心理测试', 'description');
        $this->setPageTitle($pageTitle);
		$this->render('list', array(
				'topics' => $topics,
                'pages' => $pages,
                'categories' => $categories,
                'category' => isset($category) ? $category : null
			)
		);
	}

    public function actionSubmitAnswer() {
        if(isset($_POST) && isset($_POST['PsytestForm'])) {
            $psytestForm = new PsytestForm;
            $psytestForm->attributes = $_POST['PsytestForm'];
            if($psytestForm->selectedAnswerId > 0) {
	            $psytestForm->answerAQuestion();
	            $topic = $psytestForm->answer->question->topic;
	            $question = TestQuestions::model()->getCurrentQuestion($topic);
	            $isViewConclusion = $question === null ? true : false;
	            if( ! $isViewConclusion) { // If there are still some questions
	                $this->widget('TestQuestion', array('question' => $question));
	            } else {
	                // If not, view conclusion
                    if(($userId = Yii::app()->user->id) === null) {
                        // If not logged in, set a return URL and then redirect to logging in page
                        Yii::app()->user->setReturnUrl($this->createAbsoluteUrl('/psytest/index', array('id' => $topic->topicId)));
                        echo '<script type="text/javascript">';
                        echo 'window.location.href = "'.$this->createAbsoluteUrl('/users/signin').'"';
                        echo '</script>';
                        return ;
                    }
	                $conclusions = $this->getConclusions($topic);
                    if($topic->hasTested() === false) {
	                    $this->logUserPsyTest($topic, $conclusions);
                    }
	                $this->widget('ViewTestConclusion', array('conclusions' => $conclusions));
	            }
            }
        }
    }

    public function logUserPsyTest($topic, $conclusions) {
        $userId = Yii::app()->user->id;
        if($userId !== null && count($conclusions) > 0 && $topic->hasState()) {
            $criteria = new CDbCriteria;
            $criteria->condition = 'userId = '.$userId.' AND conclusionIds = '.$conclusions[0]->conclusionId;
            $userPsytest = UserPsytest::model()->findByAttributes(array('userId' => $userId, 'topicId' => $topic->topicId));
            if($userPsytest === null) {
	            $userPsytest = new UserPsytest;
	            $userPsytest->userId = $userId;
                $userPsytest->topicId = $topic->topicId;
                $conclusionIds = array();
                foreach($conclusions as $conclusion) {
                    $conclusionIds[] = $conclusion->conclusionId;
                }
                $userPsytest->setConclusionIds($conclusionIds);
	            $userPsytest->doneAt = time();
                $userPsytest->setState($topic->getState());
	            $userPsytest->save();
                $topic->testedCount = $topic->testedCount+1;
                $topic->save();
            }
        }
    }

    public function getConclusions($topic) {
        if($topic->hasState()) {
            $state = $topic->getState();
            $result = array();
            if($topic->getTypeCatalog() == 'mark') {
                $dim2Mark = $this->getDim2Mark($topic, $state);
                $replacement = $this->getConclusionReplacement($topic, $dim2Mark);
                $conclusionOrders = array(); 
                foreach($topic->conclusions as $conclusion) {
                    $exp = 'return ';
                    $exp .= strtr($conclusion->formula, $replacement);
                    $exp .= ';';
                    //echo $exp;
                    if(@eval($exp) === true) {
                        if( ! in_array($conclusion->conclusionOrder, $conclusionOrders)) {
                        	// One conclusion is allowed in one order
                			$conclusionOrders[] = $conclusion->conclusionOrder;
                            $this->translateConclusionDescr($conclusion, $replacement);
                        	$result[] = $conclusion;
                        }
                        if($topic->topicType == TestTopics::TYPE_MARK_SINGLE_CONLUSION) {
                            break;
                        }
                    }
                }
                if($topic->generalConclusion !== null) {
                    $result[] = $topic->generalConclusion;
                    $this->translateConclusionDescr($topic->generalConclusion, $replacement);
                }
                return count($result) > 0 ? $result : null;
            } else if($topic->getTypeCatalog() == 'jumping') {
                $answerId = array_pop($state);
                if($answerId !== null) {
                    $linkage = TestAnswerLinkage::model()->findByAttributes(array('answerId' => $answerId, 'linkType' => TestAnswerLinkage::LINKTYPE_CONCLUSION));
                    if($linkage !== null) {
                        $conclusionId = $linkage->linkToId;
                        $result[] = TestConclusions::model()->findByPk($conclusionId);
                        return $result;
                    }
                }
                return null;
            }
        }
    }
    
    public function actionCreatecomment() {
		$comment = new TestComments;
    	if(isPost()) {
			$comment->attributes = $_POST['TestComments'];
			$comment->verifyCode = $_POST['TestComments']['verifyCode'];
			$comment->userId = Users::isLogin();
			$comment->commentedAt = time();
			$comment->topicId = $_POST['TestComments']['topicId'];
			if( ! $comment->save()) {
				Yii::app()->user->setFlash('testComment', serialize($comment));
			}
		}
		$this->redirect(array('psytest/index', 'id' => isset($_GET['id']) ? (int)$_GET['id'] : $comment->topicId, '#' => 'postComment'));
    }

    public function loadTestTopic($id = null) {
		if($id !== null || isset($_GET['id'])) {
			$topic = TestTopics::model()->with('comments', 'comments.author')->findByAttributes(array('topicId' => $id !== null ? $id : (int)$_GET['id']));
		}
		
        if( ! isset($topic) || $topic === null) {
			throw new CHttpException(404, 'The requested psytest does not exist.');
		}
		return $topic;
    }
}
